package org.mozhu.mboot.core.data.filter;

import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class GroupSearchFilter implements SearchFilter {

    private List<SearchFilter> searchFilters = Lists.newArrayList();

    private LogicOperator logicOperator;

    public GroupSearchFilter(List<SearchFilter> searchFilters, LogicOperator logicOperator) {
        this.searchFilters = searchFilters;
        this.logicOperator = logicOperator;
    }

    public static SearchFilter and(Collection<SearchFilter> searchFilters) {
        return newGroupSearchFilter(LogicOperator.AND, searchFilters);
    }

    public static SearchFilter or(Collection<SearchFilter> searchFilters) {
        return newGroupSearchFilter(LogicOperator.OR, searchFilters);
    }

    public static SearchFilter and(SearchFilter... searchFilters) {
        return newSearchFilter(LogicOperator.AND, searchFilters);
    }

    public static SearchFilter or(SearchFilter... searchFilters) {
        return newSearchFilter(LogicOperator.OR, searchFilters);
    }

    private static SearchFilter newGroupSearchFilter(LogicOperator logicOperator, Collection<SearchFilter> searchFilters) {
        if (CollectionUtils.isEmpty(searchFilters)) {
            throw new IllegalArgumentException("searchFilters should not be empty");
        }
        if (searchFilters.size() == 1) {
            return searchFilters.iterator().next();
        }
        return new GroupSearchFilter(Lists.newArrayList(searchFilters), logicOperator);
    }

    private static SearchFilter newSearchFilter(LogicOperator logicOperator, SearchFilter... searchFilters) {
        if (ArrayUtils.isEmpty(searchFilters)) {
            throw new IllegalArgumentException("searchFilters should not be empty");
        }
        return newGroupSearchFilter(logicOperator, Arrays.asList(searchFilters));
    }

    public List<SearchFilter> getSearchFilters() {
        return searchFilters;
    }

    public LogicOperator getLogicOperator() {
        return logicOperator;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((logicOperator == null) ? 0 : logicOperator.hashCode());
        result = prime * result + ((searchFilters == null) ? 0 : searchFilters.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        GroupSearchFilter other = (GroupSearchFilter) obj;
        if (logicOperator != other.logicOperator)
            return false;
        if (searchFilters == null) {
            if (other.searchFilters != null)
                return false;
        } else if (!searchFilters.equals(other.searchFilters))
            return false;
        return true;
    }

}
